package com.gin.no_gay_alliance.manager;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import androidx.fragment.app.FragmentActivity;

import com.fasterxml.jackson.core.type.TypeReference;
import com.gin.common.utils.FileIoUtils;
import com.gin.nga.callback.JsonCallback;
import com.gin.nga.client.NgaClient;
import com.gin.nga.enums.FavorAction;
import com.gin.nga.enums.SubForumType;
import com.gin.nga.exception.NgaClientException;
import com.gin.nga.exception.NgaException;
import com.gin.nga.method.NukeApi;
import com.gin.nga.params.nuke.favorforum.FavorForumEditParam;
import com.gin.nga.response.body.BaseMessageBody;
import com.gin.nga.response.body.nuke.FavorForumBody;
import com.gin.no_gay_alliance.app.MyApplication;
import com.gin.no_gay_alliance.callback.Callback;
import com.gin.no_gay_alliance.database.manager.AccountManager;
import com.gin.no_gay_alliance.utils.MyHandler;
import com.gin.no_gay_alliance.viewmodel.EntryData;
import com.gin.no_gay_alliance.viewmodel.EntrySubGroup;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 收藏版面管理器
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/8/7 11:37
 **/
public class FavorForumManager {
    public static final String TAG = FavorForumManager.class.getSimpleName();
    final Context context;
    final File file;
    /**
     * 缓存对象
     */
    private HashMap<Long, List<EntrySubGroup>> cache = new HashMap<>();

    public FavorForumManager(Context context) {
        Log.d(TAG, "创建:收藏版面管理器");
        this.context = context;
        this.file = new File(context.getCacheDir().getPath() + File.separator + "cache_forum/favor.json");

        if (this.file.exists()) {
            try {
                this.cache = FileIoUtils.readObj(this.file, new TypeReference<HashMap<Long, List<EntrySubGroup>>>() {
                });
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 保存缓存到文件中
     */
    public void save() {
        try {
            FileIoUtils.writeObj(this.file, cache);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加或移除收藏版面
     *
     * @param param            参数
     * @param fragmentActivity
     * @throws IOException
     */
    public void edit(FavorForumEditParam param, MyHandler handler, FragmentActivity fragmentActivity) {
        AccountManager accountManager = MyApplication.app.accountManager;
        NgaClient client = accountManager.getClient();
        Long id = param.getColTid() != null ? param.getColTid() : param.getForumId();
        String action = param.getAction();
        NukeApi.favorForumEdit(client, param).async(new JsonCallback<BaseMessageBody>() {
            @Override
            public void onSuccess(BaseMessageBody body) {
                List<EntrySubGroup> cache = FavorForumManager.this.cache.getOrDefault(client.getUserId(), new ArrayList<>());
                // 移除成功 操作缓存
                if (cache != null && FavorAction.del.name().equals(action)) {
                    cache.forEach(group -> group.entries.removeIf(i -> i.id == id));
                }
                // 添加成功 操作缓存
                if (FavorAction.add.name().equals(action)) {
                    FavorForumManager.this.cache.remove(client.getUserId());
                }
                save();
                handler.post(() -> Toast.makeText(fragmentActivity, body.getMessage(), Toast.LENGTH_SHORT).show());
            }

            @Override
            public void handleException(NgaException e) {
                super.handleException(e);
                // 请求出错，提示，强制更新收藏版面数据
                if (e instanceof NgaClientException) {
                    String s = ((NgaClientException) e).getReason().get(0);
                    handler.post(() -> Toast.makeText(fragmentActivity, s, Toast.LENGTH_SHORT).show());
                    get(true, null);
                }
            }
        });


    }

    /**
     * 获取当前账号的收藏版面列表
     *
     * @param ignoreCache 是否忽略缓存
     * @param callback    回调方法
     */
    public void get(boolean ignoreCache, Callback<List<EntrySubGroup>> callback) {
        AccountManager accountManager = MyApplication.app.accountManager;
        if (!accountManager.isLogged()) {
            Toast.makeText(context, "必须先登陆", Toast.LENGTH_SHORT).show();
            return;
        }
        NgaClient client = accountManager.getClient();
        long userId = client.getUserId();
        // 如果不忽略缓存，且缓存有数据，使用缓存
        if (!ignoreCache && cache.containsKey(userId)) {
            callback.onSuccess(cache.get(userId));
            return;
        }
        callback.beforeRequest();

        NukeApi.favorForumList(client).async(new JsonCallback<FavorForumBody>() {
            @Override
            public void onSuccess(FavorForumBody body) {
                List<EntrySubGroup> data = new ArrayList<>();

                // 版面
                List<EntryData> forums = body.getData().values().stream()
                        .filter(i -> i.getColTid() == null)
                        .map(EntryData::new)
                        .collect(Collectors.toList());
                if (!forums.isEmpty()) {
                    EntrySubGroup group = new EntrySubGroup();
                    group.name = SubForumType.FORUM.name;
                    group.entries = forums;
                    data.add(group);
                }

                //合集
                List<EntryData> cols = body.getData().values().stream()
                        .filter(i -> i.getColTid() != null)
                        .map(EntryData::new)
                        .collect(Collectors.toList());
                if (!cols.isEmpty()) {
                    EntrySubGroup group = new EntrySubGroup();
                    group.name = SubForumType.COL.name;
                    group.entries = cols;
                    data.add(group);
                }
                // 放入缓存
                cache.put(userId, data);
                save();
                //调用回调
                if (callback != null) {
                    callback.onSuccess(data);
                }
            }
        });
    }


}
